package repo

import (
	"context"
	"gitlab.yoyiit.com/youyi/go-core/handler"
	"gitlab.yoyiit.com/youyi/go-core/repository"
	"gitlab.yoyiit.com/youyi/go-core/util"
)

type CounterpartyContactDBData struct {
	repository.BaseDBData
	CounterpartyId int64  //关联的交易对手ID
	ContactName    string //联系人
	ContactPhone   string //联系电话
	ContactAddress string //联系地址
	ProvinceName   string //省名称
	ProvinceCode   string //省编码
	CityName       string //市名称
	CityCode       string //市编码
	AreaName       string //区名称
	AreaCode       string //区编码

}

type CounterpartyContactDBDataParam struct {
	CounterpartyContactDBData
	Ids []int64
}

func (*CounterpartyContactDBData) TableName() string {
	return "counterparty_contact"
}

func (param *CounterpartyContactDBData) getConditions() []*repository.Condition {
	return []*repository.Condition{
		repository.NewAndCondition(param),
	}
}

func (param *CounterpartyContactDBDataParam) listConditions() []*repository.Condition {
	var conditions []*repository.Condition

	if param.Ids != nil {
		conditions = append(conditions, repository.NewAndCondition("id in ?", param.Ids))
	}

	if param.CounterpartyId != 0 {
		conditions = append(conditions, repository.NewAndCondition("counterparty_id = ?", param.CounterpartyId))
	}
	if param.ContactName != "" {
		conditions = append(conditions, repository.NewAndCondition("contact_name = ?", param.ContactName))
	}

	if param.ContactPhone != "" {
		conditions = append(conditions, repository.NewAndCondition("contact_phone = ?", param.ContactPhone))
	}

	if param.ContactAddress != "" {
		conditions = append(conditions, repository.NewAndCondition("contact_address = ?", param.ContactAddress))
	}

	if param.ProvinceName != "" {
		conditions = append(conditions, repository.NewAndCondition("province_name = ?", param.ProvinceName))
	}

	if param.ProvinceCode != "" {
		conditions = append(conditions, repository.NewAndCondition("province_code = ?", param.ProvinceCode))
	}

	if param.CityName != "" {
		conditions = append(conditions, repository.NewAndCondition("city_name = ?", param.CityName))
	}

	if param.CityCode != "" {
		conditions = append(conditions, repository.NewAndCondition("city_code = ?", param.CityCode))
	}

	if param.AreaName != "" {
		conditions = append(conditions, repository.NewAndCondition("area_name = ?", param.AreaName))
	}

	if param.AreaCode != "" {
		conditions = append(conditions, repository.NewAndCondition("area_code = ?", param.AreaCode))
	}

	return conditions
}

type CounterpartyContactRepo interface {
	repository.BaseCommonRepo
	Get(context.Context, *CounterpartyContactDBData) (*CounterpartyContactDBData, error)
	Count(context.Context, *CounterpartyContactDBDataParam) (int64, error)
	List(context.Context, string, int32, int32, *CounterpartyContactDBDataParam) (*[]CounterpartyContactDBData, int64, error)
	SimpleList(ctx context.Context, order string, pageNum, pageSize int32, param *CounterpartyContactDBDataParam) (*[]CounterpartyContactDBData, int64, error)
}

type counterpartyContactRepo struct {
	repository.BaseRepo
}

func (r *counterpartyContactRepo) Get(ctx context.Context, param *CounterpartyContactDBData) (*CounterpartyContactDBData, error) {
	data, err := r.BaseGet(ctx, repository.NewQueryBuilder().Where(param.getConditions()))
	if data == nil {
		return nil, handler.HandleError(err)
	}
	return data.(*CounterpartyContactDBData), handler.HandleError(err)
}

func (r *counterpartyContactRepo) List(ctx context.Context, order string, pageNum, pageSize int32, param *CounterpartyContactDBDataParam) (*[]CounterpartyContactDBData, int64, error) {
	data, count, err := r.BaseList(ctx, repository.NewListQueryBuilder(order, pageNum, pageSize).Where(param.listConditions()))
	if data == nil {
		return nil, count, handler.HandleError(err)
	}
	return data.(*[]CounterpartyContactDBData), count, handler.HandleError(err)
}

func (r *counterpartyContactRepo) SimpleList(ctx context.Context, order string, pageNum, pageSize int32, param *CounterpartyContactDBDataParam) (*[]CounterpartyContactDBData, int64, error) {
	conditions := []string{}
	params := []interface{}{}

	if param.ClinicalDocument != "" {
		conditions = append(conditions, "clinical_document = ?")
		params = append(params, param.ClinicalDocument)
	}
	if param.CounterpartyId != "" {
		conditions = append(conditions, "counterparty_id = ?")
		params = append(params, param.CounterpartyId)
	}
	if param.ContactName != "" {
		conditions = append(conditions, "contact_name = ?")
		params = append(params, param.ContactName)
	}
	if param.ContactPhone != "" {
		conditions = append(conditions, "contact_phone = ?")
		params = append(params, param.ContactPhone)
	}
	if param.ContactAddress != "" {
		conditions = append(conditions, "contact_address = ?")
		params = append(params, param.ContactAddress)
	}
	if param.ProvinceName != "" {
		conditions = append(conditions, "province_name = ?")
		params = append(params, param.ProvinceName)
	}
	if param.ProvinceCode != "" {
		conditions = append(conditions, "province_code = ?")
		params = append(params, param.ProvinceCode)
	}
	if param.CityName != "" {
		conditions = append(conditions, "city_name = ?")
		params = append(params, param.CityName)
	}
	if param.CityCode != "" {
		conditions = append(conditions, "city_code = ?")
		params = append(params, param.CityCode)
	}
	if param.AreaName != "" {
		conditions = append(conditions, "area_name = ?")
		params = append(params, param.AreaName)
	}
	if param.AreaCode != "" {
		conditions = append(conditions, "area_code = ?")
		params = append(params, param.AreaCode)
	}

	var count int64
	err := r.Db.WithContext(ctx).Model(r.Model).Where(strings.Join(conditions, " and "), params...).Count(&count).Error
	if err != nil {
		return nil, 0, handler.HandleError(err)
	}
	if count == 0 {
		return nil, 0, nil
	}
	var result []CounterpartyContactDBData
	db := r.Db.WithContext(ctx).Where(strings.Join(conditions, " and "), params...)
	if order != "" {
		db = db.Order(order)
	}
	if pageNum > 0 && pageSize > 0 {
		db = db.Offset(int((pageNum - 1) * pageSize))
		db = db.Limit(int(pageSize))
	}
	err = db.Find(&result).Error
	return &result, count, handler.HandleError(err)
}

func (r *counterpartyContactRepo) Count(ctx context.Context, param *CounterpartyContactDBDataParam) (int64, error) {
	count, err := r.BaseCount(ctx, repository.NewQueryBuilder().Where(param.listConditions()))
	return count, handler.HandleError(err)
}
